
package com.cxk.hr.security;

import java.util.concurrent.atomic.AtomicInteger;


import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;

/**
 * 密码匹配记录
 * 
 * @author: 84157
 * @Desc: 如果登陆不对，则记录，五次后提示
 * 
 */
public class CustomCredentialsMatcher extends HashedCredentialsMatcher {
	private Cache<String, AtomicInteger> passwordRetryCache;

	/**
	 * 
	 * @param cacheManager
	 */
	public CustomCredentialsMatcher(CacheManager cacheManager) {
		passwordRetryCache = cacheManager.getCache("passwordRetryCache");
	}

	/**
	 * 密码验证方法
	 * 
	 * @param token(从客户输入获取token(令牌))
	 * @param info(SecurityRealm中doGetAuthenticationInfo返回的info(输入的密码加密加盐))
	 */
	@Override
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
		String loginName = (String) token.getPrincipal();
		AtomicInteger retryCount = passwordRetryCache.get(loginName);
		if (retryCount == null) {
			retryCount = new AtomicInteger(0);
		}

		// 将缓存记录的登录次数加1
		retryCount.incrementAndGet();
		if (retryCount.get() > 5) {
			throw new ExcessiveAttemptsException();
		}

		passwordRetryCache.put(loginName, retryCount);
		boolean matchs = super.doCredentialsMatch(token, info);// 比对数据库中密码和输入的密码
		if (matchs) {
			passwordRetryCache.remove(loginName);
			return true;
		}
		passwordRetryCache.remove(loginName);
		return false;
	}

	public Cache<String, AtomicInteger> getPasswordRetryCache() {
		return passwordRetryCache;
	}

	public void setPasswordRetryCache(Cache<String, AtomicInteger> passwordRetryCache) {
		this.passwordRetryCache = passwordRetryCache;
	}
}
